<template>
  <div
    class="flex"
    v-click-outside="onClickOutside"
  >
    <el-popover
      popper-class="t-custom-select-popover"
      ref="popoverRef"
      :visible="visible"
      :virtual-ref="virtualRef"
      trigger="click"
      virtual-triggering
      placement="bottom"
      :width="width"
      app
    >
      <div
        class="input-wrap"
        v-if="filterable"
      >
        <el-input
          size="default"
          class="popover-filter-input mb6"
          v-model="filterText"
          @input="handleFilter"
        />
      </div>
      <el-scrollbar style="height: 200px">
        <template
          v-for="option in optionList"
          :key="option[optionProps.value]"
        >
          <div
            class="el-dropdown-menu__item"
            :class="[option[optionProps.value] === targetItem[targetKey] ? 'el-dropdown-menu__item__active' : '']"
            v-if="!filterOptionsKey.includes(option[optionProps.value])"
            @click="handleOptionClick(option[optionProps.value])"
          >
            {{ option[optionProps.label] }}
          </div>
        </template>
      </el-scrollbar>
    </el-popover>
  </div>
</template>

<script setup>
import { onMounted, onUnmounted, ref, watch } from "vue";
import { cloneDeep } from "lodash-es";
import { ClickOutside as vClickOutside } from "element-plus";

const visible = ref(false);

const virtualRef = ref(null);

const width = ref("200px");

const popoverRef = ref(null);

const props = defineProps({
  options: {
    type: Array,
    default: () => []
  },
  optionProps: {
    type: Object,
    default: () => ({
      label: "label",
      value: "value"
    })
  },
  filterable: {
    type: Boolean,
    default: false
  }
});

const optionList = ref([]);

const filterOptionsKey = ref([]);

const emit = defineEmits(["change"]);

watch(
  () => props.options,
  () => {
    optionList.value = cloneDeep(props.options);
  },
  {
    immediate: true,
    deep: true
  }
);

const filterText = ref("");

const handleFilter = val => {
  filterText.value = val;
  if (val) {
    optionList.value = optionList.value.filter(item => item[props.optionProps.label].includes(val));
  } else {
    optionList.value = cloneDeep(props.options);
  }
};

const targetItem = ref({});

const targetKey = ref("");

/**
 * 点击事件
 * @param event 事件
 * @param item 修改数据
 * @param key 数据key
 * @param fKeys 过滤数据key
 */
const handleClick = (event, item, key, fKeys) => {
  let targetDom = event.target;
  // 如果点击的是带.el-select__placeholder得
  if (event.target.classList.contains("el-select__placeholder")) {
    // 拿父元素
    targetDom = event.target.parentNode;
  }

  virtualRef.value = targetDom;
  // 给target加上边框
  targetDom.style.boxShadow = "0 0 0 1px var(--el-color-primary) inset";
  // 移除样式
  targetDom.classList.remove("logic-custom-select");
  targetDom.classList.add("logic-custom-select-expand");
  // 宽度等于父元素的宽度
  width.value = `${targetDom.offsetWidth}px`;
  visible.value = true;
  targetItem.value = item;
  targetKey.value = key;
  filterOptionsKey.value = fKeys || [];
};

const handleOptionClick = val => {
  handleShow();
  targetItem.value[targetKey.value] = val;
  emit("change", val);
};

const onClickOutside = event => {
  console.log(event.target.classList);
  if (event.target.classList.contains("popover-filter-input") || event.target.classList.contains("el-input__inner")) {
    return;
  }
  handleShow();
};

// 恢复显示
const handleShow = () => {
  if (virtualRef.value) {
    virtualRef.value.style.boxShadow = "none";
    virtualRef.value.classList.add("logic-custom-select");
    virtualRef.value.classList.remove("logic-custom-select-expand");
  }
  visible.value = false;
};

onMounted(() => {
  const scrollableDiv = document.querySelector(".logic-scrollbar-wrap");
  if (scrollableDiv) {
    scrollableDiv.addEventListener("scroll", () => {
      handleShow();
    });
  }
});

onUnmounted(() => {
  const scrollableDiv = document.querySelector(".logic-scrollbar-wrap");
  if (scrollableDiv) {
    scrollableDiv.addEventListener("scroll", () => {});
  }
});

defineExpose({
  handleClick
});
</script>
<style lang="scss" scoped>
.el-dropdown-menu__item:hover {
  background-color: var(--el-bg-color-page);
}
.el-dropdown-menu__item {
  //文字超出隐藏
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.el-dropdown-menu__item__active {
  color: var(--el-color-primary);
}
</style>
<style lang="scss">
.t-custom-select-popover {
  --el-popover-padding: 2px;
}
</style>
